λμ νλ¬κ·ΈμΈ μμ€ν ꡬμΆμ μν μλ°μ€ν¬λ¦½νΈ λͺ¨λ νλλ μ΄μ μ νꡬν©λλ€. νμ₯ κ°λ₯νκ³ μ μ§λ³΄μ μ©μ΄ν μ ν리μΌμ΄μ μ μν μν€ν μ², ꡬν, 보μ λ° λͺ¨λ² μ¬λ‘λ₯Ό λ°°μ보μΈμ.
μλ°μ€ν¬λ¦½νΈ λͺ¨λ νλλ μ΄μ νλ¬κ·ΈμΈ μν€ν μ²: λμ νλ¬κ·ΈμΈ μμ€ν ꡬμΆ
μ€λλ 볡μ‘ν μΉ κ°λ° νκ²½μμλ λͺ¨λμμ΄κ³ νμ₯ κ°λ₯νλ©° μ μ§λ³΄μ μ©μ΄ν μ ν리μΌμ΄μ μ ꡬμΆνλ κ²μ΄ μ€μν©λλ€. μ΄λ₯Ό λ¬μ±νκΈ° μν κ°λ ₯ν κΈ°μ μ€ νλλ νλ¬κ·ΈμΈ μν€ν μ²λ₯Ό ν΅νλ κ²μ΄λ©°, μ¬κΈ°μ κΈ°λ₯μ λ 립μ μ΄κ³ λμ μΌλ‘ λ‘λλλ λͺ¨λλ‘ λΆλ¦¬λ©λλ€. Webpack 5μ κΈ°λ₯μΈ μλ°μ€ν¬λ¦½νΈ λͺ¨λ νλλ μ΄μ μ μ΄λ¬ν μν€ν μ²λ₯Ό ꡬννκΈ° μν κ²¬κ³ ν λ©μ»€λμ¦μ μ 곡ν©λλ€. μ΄ κΈμμλ λͺ¨λ νλλ μ΄μ μ μ¬μ©νμ¬ λμ νλ¬κ·ΈμΈ μμ€ν μ ꡬμΆνλ 볡μ‘ν κ³Όμ μ λν΄ μμΈν μμλ΄ λλ€.
λͺ¨λ νλλ μ΄μ μ΄λ 무μμΈκ°?
λͺ¨λ νλλ μ΄μ μ μλ°μ€ν¬λ¦½νΈ μ ν리μΌμ΄μ μ΄ λ°νμμ μ½λλ₯Ό λμ μΌλ‘ 곡μ ν μ μκ² ν΄μ€λλ€. μ¦, ν μ ν리μΌμ΄μ μ λͺ¨λ(μ½λ μ‘°κ°)μ λ€λ₯Έ μ ν리μΌμ΄μ μμ λ€μ λΉλνκ±°λ μ¬λ°°ν¬ν νμ μμ΄ μ§μ μ¬μ©ν μ μμ΅λλ€. μ΄λ μλ‘ λ€λ₯Έ λΉλ, μ¬μ§μ΄ λ€λ₯Έ λ°°ν¬ νκ²½μ κ±Έμ³ λͺ¨λμ λ ΈμΆνκ³ μλΉν¨μΌλ‘μ¨ λ¬μ±λ©λλ€.
npm ν¨ν€μ§μ κ°μ κΈ°μ‘΄μ μ½λ 곡μ λ°©μμ 곡μ μ’ μμ±μ΄ μ λ°μ΄νΈλ λλ§λ€ μλΉνλ μ ν리μΌμ΄μ μ λ€μ λΉλνκ³ μ¬λ°°ν¬ν΄μΌ ν©λλ€. λͺ¨λ νλλ μ΄μ μ μ΄λ¬ν μ€λ²ν€λλ₯Ό μ κ±°νμ¬ λΉλ²ν μ λ°μ΄νΈμ λ 립μ μΈ λ°°ν¬κ° νμν μλ리μ€μ μ΄μμ μ λλ€.
νλ¬κ·ΈμΈ μν€ν μ²μ λͺ¨λ νλλ μ΄μ μ μ¬μ©νλ μ΄μ λ 무μμΈκ°?
λͺ¨λ νλλ μ΄μ μ νλ¬κ·ΈμΈ μν€ν μ²λ₯Ό ꡬμΆν λ μ¬λ¬ κ°μ§ μ΄μ μ μ 곡ν©λλ€:
- λμ λͺ¨λ λ‘λ©: νλ¬κ·ΈμΈμ λ°νμμ λ‘λνκ³ μΈλ‘λν μ μμ΄, μ ν리μΌμ΄μ μ΄ μ 체 μ¬λ°°ν¬ μμ΄ λ³ννλ μꡬμ¬νμ μ μν μ μμ΅λλ€.
- λ컀νλ§: νλ¬κ·ΈμΈμ λ 립μ μΌλ‘ κ°λ° λ° λ°°ν¬λμ΄ μ ν리μΌμ΄μ μ λ€λ₯Έ λΆλΆ κ°μ μ’ μμ±μ μ€μ λλ€.
- νμ₯μ±: κΈ°μ‘΄ κΈ°λ₯μ μν₯μ μ£Όμ§ μκ³ μλ‘μ΄ νλ¬κ·ΈμΈμΌλ‘ μ ν리μΌμ΄μ μ μ½κ² νμ₯ν μ μμ΅λλ€.
- μ μ§λ³΄μμ±: νλ¬κ·ΈμΈμ λ 립μ μΌλ‘ μ λ°μ΄νΈνκ³ μ μ§λ³΄μν μ μμ΄ ν΅μ¬ μ ν리μΌμ΄μ μ λ²κ·Έκ° μ μ λ μνμ μ€μ λλ€.
- μ½λ μ¬μ¬μ©: μ¬λ¬ μ ν리μΌμ΄μ μμ νλ¬κ·ΈμΈμ μ¬μ¬μ©νμ¬ μΌκ΄μ±μ λμ΄κ³ κ°λ° λ Έλ ₯μ μ€μΌ μ μμ΅λλ€.
- λ²μ κ΄λ¦¬ λ° λ‘€λ°±: λ€μν λ²μ μ νλ¬κ·ΈμΈμ κ΄λ¦¬νκ³ νμν κ²½μ° μ΄μ λ²μ μΌλ‘ μ½κ² λ‘€λ°±ν μ μμ΅λλ€.
ν΅μ¬ κ°λ : νΈμ€νΈμ μ격 컨ν μ΄λ
λͺ¨λ νλλ μ΄μ μ λ κ°μ§ ν΅μ¬ κ°λ μ μ€μ¬μΌλ‘ ν©λλ€:
- νΈμ€νΈ 컨ν μ΄λ(Host Container): μ격 λͺ¨λ(νλ¬κ·ΈμΈ)μ μλΉνλ λ©μΈ μ ν리μΌμ΄μ μ λλ€.
- μ격 컨ν μ΄λ(Remote Container): νΈμ€νΈκ° μλΉν λͺ¨λ(νλ¬κ·ΈμΈ)μ λ ΈμΆνλ μ ν리μΌμ΄μ μ λλ€.
νΈμ€νΈ 컨ν μ΄λλ μ격 컨ν μ΄λλ‘λΆν° μ격 μ§μ νμΌ(remote entry file)μ λμ μΌλ‘ κ°μ Έμ΅λλ€. μ΄ νμΌμλ λ ΈμΆλ λͺ¨λμ λ§€λνμ€νΈκ° ν¬ν¨λμ΄ μμ΅λλ€. κ·Έλ¬λ©΄ νΈμ€νΈλ μ΄λ¬ν λͺ¨λμ λ§μΉ μμ μ μ½λλ² μ΄μ€μ μΌλΆμΈ κ²μ²λΌ μ κ·Όνκ³ μ¬μ©ν μ μμ΅λλ€.
λͺ¨λ νλλ μ΄μ μ μ΄μ©ν λμ νλ¬κ·ΈμΈ μμ€ν ꡬν: λ¨κ³λ³ κ°μ΄λ
λͺ¨λ νλλ μ΄μ μ μ¬μ©νμ¬ κ°λ¨ν νλ¬κ·ΈμΈ μμ€ν μ ꡬμΆνλ κ³Όμ μ μ΄ν΄λ³΄κ² μ΅λλ€. μ°λ¦¬λ νΈμ€νΈ μ ν리μΌμ΄μ κ³Ό μ격 νλ¬κ·ΈμΈ μ ν리μΌμ΄μ μ λ§λ€ κ²μ λλ€.
1. νΈμ€νΈ μ ν리μΌμ΄μ μ€μ νκΈ° (νΈμ€νΈ 컨ν μ΄λ)
λ¨Όμ , μ νλ‘μ νΈ λλ ν 리λ₯Ό λ§λ€κ³ μ npm νλ‘μ νΈλ₯Ό μ΄κΈ°νν©λλ€:
mkdir host-app
cd host-app
npm init -y
Webpackκ³Ό κ΄λ ¨ μ’ μμ±μ μ€μΉν©λλ€:
npm install webpack webpack-cli webpack-dev-server html-webpack-plugin --save-dev
`host-app` λλ ν 리μ λ€μ μ€μ μΌλ‘ `webpack.config.js` νμΌμ μμ±ν©λλ€:
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');
const path = require('path');
module.exports = {
mode: 'development',
devtool: 'source-map',
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
},
devServer: {
port: 3000,
hot: true,
static: {
directory: path.join(__dirname, 'dist'),
},
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env', '@babel/preset-react'],
},
},
},
],
},
plugins: [
new ModuleFederationPlugin({
name: 'Host',
remotes: {
'plugin': 'Plugin@http://localhost:3001/remoteEntry.js',
},
shared: ['react', 'react-dom'],
}),
new HtmlWebpackPlugin({
template: './public/index.html',
}),
],
};
μ€λͺ :
- `name`: νΈμ€νΈ μ ν리μΌμ΄μ μ μ΄λ¦μ λλ€.
- `remotes`: νΈμ€νΈκ° μλΉν μ격 컨ν μ΄λλ₯Ό μ μν©λλ€. μ΄ κ²½μ°, `http://localhost:3001/remoteEntry.js`μμ `plugin`μ΄λΌλ μ΄λ¦μ μ격 컨ν μ΄λλ₯Ό μλΉν©λλ€. `Plugin@` ꡬ문μ μ격μ ModuleFederationPluginμ `name`μ΄ 'Plugin'μμ μλ―Έν©λλ€.
- `shared`: νΈμ€νΈμ μ격 컨ν μ΄λ κ°μ 곡μ λλ μ’ μμ± λͺ©λ‘μ λλ€. μ΄λ μ΄λ¬ν μ’ μμ±μ μ€λ³΅λ 볡μ¬λ³Έμ΄ λ‘λλλ κ²μ λ°©μ§ν©λλ€. `shared`λ₯Ό μ¬μ©νλ κ²μ μ€λ₯λ₯Ό νΌνκ³ μ μ ν νλ¬κ·ΈμΈ κΈ°λ₯μ 보μ₯νλ λ° μ€μν©λλ€.
`src` λλ ν 리λ₯Ό λ§λ€κ³ λ€μ λ΄μ©μΌλ‘ `index.js` νμΌμ μΆκ°ν©λλ€:
import React, { Suspense } from 'react';
import ReactDOM from 'react-dom/client';
const PluginComponent = React.lazy(() => import('plugin/PluginComponent'));
const App = () => {
return (
<div>
<h1>Host Application</h1>
<Suspense fallback={<div>Loading Plugin...</div>}>
<PluginComponent />
</Suspense>
</div>
);
};
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
μ€λͺ :
- `plugin` μ격μμ `PluginComponent`λ₯Ό λμ μΌλ‘ κ°μ Έμ€κΈ° μν΄ `React.lazy`λ₯Ό μ¬μ©νκ³ μμ΅λλ€. μ΄λ νλ¬κ·ΈμΈμ μ§μ° λ‘λ©νκ³ μ΄κΈ° λ‘λ μ§μ°μ νΌνλ λ° μ€μν©λλ€.
- `Suspense` μ»΄ν¬λνΈλ νλ¬κ·ΈμΈμ κ°μ Έμ€λ λμ λ‘λ© μνλ₯Ό μ²λ¦¬νλ λ° μ¬μ©λ©λλ€.
`public` λλ ν 리λ₯Ό λ§λ€κ³ λ€μ λ΄μ©μΌλ‘ `index.html` νμΌμ μΆκ°ν©λλ€:
<!DOCTYPE html>
<html>
<head>
<title>Host Application</title>
</head>
<body>
<div id="root"></div>
<script src="./bundle.js"></script>
</body>
</html>
Babel μ€μ νμΌ `.babelrc`λ₯Ό μΆκ°ν©λλ€:
{
"presets": ["@babel/preset-env", "@babel/preset-react"]
}
`package.json`μ μμ μ€ν¬λ¦½νΈλ‘ μ λ°μ΄νΈν©λλ€:
{
"name": "host-app",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "webpack serve --mode development",
"build": "webpack --mode production"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.23.9",
"@babel/preset-env": "^7.23.9",
"@babel/preset-react": "^7.23.3",
"babel-loader": "^9.1.3",
"html-webpack-plugin": "^5.6.0",
"webpack": "^5.90.3",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^4.15.1"
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
}
}
2. μ격 μ ν리μΌμ΄μ μ€μ νκΈ° (νλ¬κ·ΈμΈ 컨ν μ΄λ)
νλ¬κ·ΈμΈμ μν μ νλ‘μ νΈ λλ ν 리λ₯Ό λ§λλλ€:
mkdir plugin-app
cd plugin-app
npm init -y
Webpackκ³Ό κ΄λ ¨ μ’ μμ±μ μ€μΉν©λλ€:
npm install webpack webpack-cli webpack-dev-server html-webpack-plugin --save-dev
`plugin-app` λλ ν 리μ λ€μ μ€μ μΌλ‘ `webpack.config.js` νμΌμ μμ±ν©λλ€:
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');
const path = require('path');
module.exports = {
mode: 'development',
devtool: 'source-map',
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
},
devServer: {
port: 3001,
hot: true,
static: {
directory: path.join(__dirname, 'dist'),
},
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env', '@babel/preset-react'],
},
},
},
],
},
plugins: [
new ModuleFederationPlugin({
name: 'Plugin',
filename: 'remoteEntry.js',
exposes: {
'./PluginComponent': './src/PluginComponent',
},
shared: ['react', 'react-dom'],
}),
new HtmlWebpackPlugin({
template: './public/index.html',
}),
],
};
μ€λͺ :
- `name`: μ격 컨ν μ΄λ(νλ¬κ·ΈμΈ)μ μ΄λ¦μ λλ€. μ΄ μ΄λ¦μ νΈμ€νΈμ `remotes` μ€μ μ μ¬μ©λ μ΄λ¦κ³Ό **λ°λμ** μΌμΉν΄μΌ ν©λλ€.
- `filename`: νΈμ€νΈκ° κ°μ Έμ¬ μ격 μ§μ νμΌμ μ΄λ¦μ λλ€.
- `exposes`: μ격 컨ν μ΄λκ° λ ΈμΆνλ λͺ¨λμ μ μν©λλ€. μ΄ κ²½μ°, `PluginComponent` λͺ¨λμ λ ΈμΆν©λλ€. ν€ './PluginComponent'λ νΈμ€νΈμ import λ¬Έμμ μ¬μ©λ©λλ€ (μ: `import('plugin/PluginComponent')`).
- `shared`: νΈμ€νΈμ λ§μ°¬κ°μ§λ‘ 곡μ μ’ μμ± λͺ©λ‘μ λλ€. νΈμ€νΈμ μ격 κ°μ 곡μ μ’ μμ±κ³Ό κ·Έ λ²μ μ΄ νΈνλλ κ²μ΄ λ§€μ° μ€μν©λλ€.
`src` λλ ν 리λ₯Ό λ§λ€κ³ λ€μ λ΄μ©μΌλ‘ `PluginComponent.jsx` νμΌμ μΆκ°ν©λλ€:
import React from 'react';
const PluginComponent = () => {
return (
<div style={{border: '1px solid blue', padding: '10px'}}>
<h2>Plugin Component</h2>
<p>This is a dynamically loaded plugin!</p>
</div>
);
};
export default PluginComponent;
`src` λλ ν 리μ PluginComponentλ₯Ό λ΄λ³΄λ΄κΈ° μν `index.js` νμΌμ μμ±ν©λλ€:
import PluginComponent from './PluginComponent';
export default PluginComponent;
`public` λλ ν 리λ₯Ό λ§λ€κ³ λ€μ λ΄μ©μΌλ‘ `index.html` νμΌμ μΆκ°ν©λλ€:
<!DOCTYPE html>
<html>
<head>
<title>Plugin Application</title>
</head>
<body>
<div id="root"></div>
<script src="./bundle.js"></script>
</body>
</html>
Babel μ€μ νμΌ `.babelrc`λ₯Ό μΆκ°ν©λλ€:
{
"presets": ["@babel/preset-env", "@babel/preset-react"]
}
`package.json`μ μμ μ€ν¬λ¦½νΈλ‘ μ λ°μ΄νΈν©λλ€:
{
"name": "plugin-app",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "webpack serve --mode development",
"build": "webpack --mode production"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.23.9",
"@babel/preset-env": "^7.23.9",
"@babel/preset-react": "^7.23.3",
"babel-loader": "^9.1.3",
"html-webpack-plugin": "^5.6.0",
"webpack": "^5.90.3",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^4.15.1"
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
}
}
3. μ ν리μΌμ΄μ μ€ννκΈ°
κ° λλ ν 리μμ `npm start`λ₯Ό μ€ννμ¬ νΈμ€νΈμ νλ¬κ·ΈμΈ μ ν리μΌμ΄μ μ λͺ¨λ μμν©λλ€.
λΈλΌμ°μ μμ `http://localhost:3000`μΌλ‘ μ΄λν©λλ€. λμ μΌλ‘ λ‘λλ νλ¬κ·ΈμΈ μ»΄ν¬λνΈμ ν¨κ» νΈμ€νΈ μ ν리μΌμ΄μ μ΄ νμλμ΄μΌ ν©λλ€.
κ³ κΈ κΈ°λ₯ λ° κ³ λ €μ¬ν
λ²μ κ΄λ¦¬ λ° λ‘€λ°±
λͺ¨λ νλλ μ΄μ μ λ²μ κ΄λ¦¬λ₯Ό μ§μνμ¬ λ€μν λ²μ μ νλ¬κ·ΈμΈμ κ΄λ¦¬ν μ μμ΅λλ€. νΈμ€νΈμ `remotes` μ€μ μμ λ²μ μ μ½ μ‘°κ±΄μ μ§μ ν μ μμ΅λλ€. μλ₯Ό λ€μ΄:
remotes: {
'plugin': 'Plugin@http://localhost:3001/remoteEntry.js@1.0.0',
}
μ΄λ νΈμ€νΈμκ² νλ¬κ·ΈμΈμ 1.0.0 λ²μ μ μ¬μ©νλλ‘ μ§μν©λλ€. λ μλ‘μ΄ λ²μ μ΄ μλλΌλ, λͺ μμ μΌλ‘ μ λ°μ΄νΈλ λκΉμ§ νΈμ€νΈλ μ§μ λ λ²μ μ κ³μ μ¬μ©ν©λλ€. κ²¬κ³ ν λ²μ κ΄λ¦¬ ꡬνμ νΈνμ±μ΄ κΉ¨μ§λ λ³κ²½μ λ°©μ§νκ³ μ ν리μΌμ΄μ μμ μ±μ 보μ₯νλ λ° μ€μν©λλ€.
보μ κ³ λ €μ¬ν
λͺ¨λ νλλ μ΄μ μ μ¬μ©ν λ 보μμ κ°μ₯ μ€μν©λλ€. λ€μμ κ³ λ €νμμμ€:
- μΈμ¦ λ° μΈκ°: μ μ ν μΈμ¦ λ° μΈκ° λ©μ»€λμ¦μ ꡬννμ¬ νκ°λ μ¬μ©μλ§ νλ¬κ·ΈμΈμ μ κ·Όνκ³ μ¬μ©ν μ μλλ‘ ν©λλ€.
- μ½λ 무결μ±: μ격 λͺ¨λμ 무결μ±μ κ²μ¦νμ¬ μ μ± μ½λκ° μ ν리μΌμ΄μ μ μ£Όμ λλ κ²μ λ°©μ§ν©λλ€. μ½ν μΈ λ³΄μ μ μ± (CSP)μ μ¬μ©νμ¬ μ ν리μΌμ΄μ μ΄ λ¦¬μμ€λ₯Ό λ‘λν μ μλ μμ€λ₯Ό μ ννλ κ²μ κ³ λ €νμμμ€.
- μ’ μμ± κ΄λ¦¬: νΈμ€νΈμ μ격 컨ν μ΄λ λͺ¨λμ μ’ μμ±μ μ μ€νκ² κ΄λ¦¬νμ¬ μ·¨μ½μ μ νΌν©λλ€. μ κΈ°μ μΌλ‘ μ’ μμ±μ μ΅μ λ²μ μΌλ‘ μ λ°μ΄νΈνμμμ€.
- μ λ ₯ μ ν¨μ± κ²μ¬: μ격 λͺ¨λλ‘λΆν° λ°μ λͺ¨λ λ°μ΄ν°λ₯Ό μ ν¨μ± κ²μ¬νμ¬ μ£Όμ 곡격μ λ°©μ§ν©λλ€.
- CORS (Cross-Origin Resource Sharing): νΈμ€νΈ μ ν리μΌμ΄μ μ΄ νλ¬κ·ΈμΈ μ ν리μΌμ΄μ μ μ격 μ§μ νμΌμ μ κ·Όν μ μλλ‘ CORSλ₯Ό μ μ νκ² κ΅¬μ±ν©λλ€.
νλ¬κ·ΈμΈ κ²μ λ° κ΄λ¦¬
λ 볡μ‘ν νλ¬κ·ΈμΈ μμ€ν μ κ²½μ°, νλ¬κ·ΈμΈμ κ²μνκ³ κ΄λ¦¬νλ λ©μ»€λμ¦μ΄ νμν μ μμ΅λλ€. μ΄λ νλ¬κ·ΈμΈ λ μ§μ€νΈλ¦¬λ κ²μ μλΉμ€λ₯Ό ν΅ν΄ λ¬μ±ν μ μμ΅λλ€. μ€μ λ μ§μ€νΈλ¦¬λ μ¬μ© κ°λ₯ν νλ¬κ·ΈμΈμ λν μ 보(μμΉ, λ²μ , μ’ μμ± λ±)λ₯Ό μ μ₯ν μ μμ΅λλ€. κ·Έλ¬λ©΄ νΈμ€νΈ μ ν리μΌμ΄μ μ λ μ§μ€νΈλ¦¬λ₯Ό 쿼리νμ¬ μ μ ν νλ¬κ·ΈμΈμ μ°Ύμ λ‘λν μ μμ΅λλ€.
λ€μ μ κ·Ό λ°©μμ κ³ λ €νμμμ€:
- μ€μ μ§μ€μ ꡬμ±: νλ¬κ·ΈμΈ URLμ μ€μ κ΅¬μ± νμΌ(μ: JSON νμΌ)μ μ μ₯νκ³ νΈμ€νΈ μ ν리μΌμ΄μ μ΄ λ°νμμ μ΄λ₯Ό μ½λλ‘ ν©λλ€. μ΄λ₯Ό ν΅ν΄ νΈμ€νΈ μ ν리μΌμ΄μ μ μ¬λ°°ν¬νμ§ μκ³ λ νλ¬κ·ΈμΈμ μ½κ² μΆκ°, μ κ±° λλ μ λ°μ΄νΈν μ μμ΅λλ€.
- API κΈ°λ° κ²μ: μ¬μ© κ°λ₯ν νλ¬κ·ΈμΈ λͺ©λ‘μ λ°ννλ API μλν¬μΈνΈλ₯Ό λ§λλλ€. κ·Έλ¬λ©΄ νΈμ€νΈ μ ν리μΌμ΄μ μ΄ μ΄ λͺ©λ‘μ κ°μ Έμ νλ¬κ·ΈμΈμ λμ μΌλ‘ λ‘λν μ μμ΅λλ€.
- μ΄λ²€νΈ κΈ°λ° μν€ν μ²: μ΄λ²€νΈ λ²μ€λ λ©μμ§ νλ₯Ό μ¬μ©νμ¬ μ νλ¬κ·ΈμΈμ΄ μ¬μ© κ°λ₯ν λ νΈμ€νΈ μ ν리μΌμ΄μ μ μ립λλ€. μ΄λ λΉλκΈ°μ νλ¬κ·ΈμΈ κ²μ λ° λ‘λ©μ κ°λ₯νκ² ν©λλ€.
λμ κ΅¬μ± λ° νλ¬κ·ΈμΈ νμ±ν
μ¬μ©μκ° νλ¬κ·ΈμΈμ λμ μΌλ‘ ꡬμ±νκ³ νμ±νν μ μλλ‘ νλ κ²μ κ°λ ₯ν κΈ°λ₯μ λλ€. μ΄λ₯Ό μν΄μλ νλ¬κ·ΈμΈ ꡬμ±μ μ μ₯νκ³ κ΄λ¦¬νλ λ©μ»€λμ¦μ΄ νμν©λλ€. λ°μ΄ν°λ² μ΄μ€, κ΅¬μ± νμΌ λλ ν΄λΌμ°λ κΈ°λ° κ΅¬μ± μλΉμ€λ₯Ό μ¬μ©νμ¬ νλ¬κ·ΈμΈ μ€μ μ μ μ₯ν μ μμ΅λλ€. κ·Έλ¬λ©΄ νΈμ€νΈ μ ν리μΌμ΄μ μ λ°νμμ μ΄λ¬ν μ€μ μ μ½κ³ κ·Έμ λ°λΌ νλ¬κ·ΈμΈμ νμ±νν μ μμ΅λλ€. νλ¬κ·ΈμΈ ꡬμ±μ κ΄λ¦¬νκΈ° μν μ¬μ©μ μΈν°νμ΄μ€λ₯Ό μ 곡νλ κ²μ κ³ λ €νμμμ€.
λΉλκΈ° μμ λ° μ€λ₯ μ²λ¦¬
λμ μΌλ‘ λ‘λλ νλ¬κ·ΈμΈμΌλ‘ μμ ν λλ λΉλκΈ° μμ κ³Ό μ€λ₯λ₯Ό μ μμ μΌλ‘ μ²λ¦¬νλ κ²μ΄ νμμ μ λλ€. λΉλκΈ° μ½λλ₯Ό κ΄λ¦¬νκΈ° μν΄ `async/await`λ Promisesλ₯Ό μ¬μ©νμμμ€. νλ¬κ·ΈμΈ λ‘λ© λλ μ€ν μ€μ λ°μνλ λͺ¨λ μ€λ₯λ₯Ό ν¬μ°©νκ³ κΈ°λ‘νκΈ° μν΄ μ μ ν μ€λ₯ μ²λ¦¬λ₯Ό ꡬννμμμ€. μ¬μ©μμκ² μ μ©ν μ€λ₯ λ©μμ§λ₯Ό μ 곡νμμμ€. λͺ¨λ νλ¬κ·ΈμΈμμ λ°μνλ μ€λ₯λ₯Ό μΆμ νκΈ° μν΄ μ€μ μ§μ€μ μ€λ₯ λ‘κΉ μλΉμ€λ₯Ό μ¬μ©νλ κ²μ κ³ λ €νμμμ€.
μ½λ λΆν λ° μ±λ₯ μ΅μ ν
μ±λ₯μ μ΅μ ννλ €λ©΄ μ½λ λΆν μ μ¬μ©νμ¬ μ ν리μΌμ΄μ κ³Ό νλ¬κ·ΈμΈμ λ μμ μ²ν¬λ‘ λλλλ€. μ΄λ₯Ό ν΅ν΄ λΈλΌμ°μ λ νΉμ νμ΄μ§λ κΈ°λ₯μ νμν μ½λλ§ λ€μ΄λ‘λν μ μμ΅λλ€. Webpackμ μ½λ λΆν μ μν λ΄μ₯ μ§μμ μ 곡ν©λλ€. νμν λλ§ νλ¬κ·ΈμΈμ λ‘λνκΈ° μν΄ μ§μ° λ‘λ©μ μ¬μ©νλ κ²μ κ³ λ €νμμμ€. νμΌ ν¬κΈ°λ₯Ό μ€μ΄κΈ° μν΄ μ½λλ₯Ό μΆμνκ³ μμΆνμμμ€.
ν μ€νΈ λ° μ§μμ ν΅ν©
νλ¬κ·ΈμΈ μμ€ν μ΄ μ¬λ°λ₯΄κ² μλνλμ§ νμΈνκΈ° μν΄ μ² μ ν ν μ€νΈνμμμ€. λ¨μ ν μ€νΈ, ν΅ν© ν μ€νΈ λ° μλν¬μλ ν μ€νΈλ₯Ό μμ±νμμμ€. μ½λκ° λ³κ²½λ λλ§λ€ μλμΌλ‘ ν μ€νΈλ₯Ό μ€ννκΈ° μν΄ μ§μμ ν΅ν©(CI) μμ€ν μ μ¬μ©νμμμ€. μ ν리μΌμ΄μ κ³Ό νλ¬κ·ΈμΈμ λ°°ν¬λ₯Ό μλννκΈ° μν΄ μ§μμ μ λ¬(CD) νμ΄νλΌμΈμ ꡬννμμμ€.
μ€μ μ¬λ‘ λ° μ¬μ© μμ
λͺ¨λ νλλ μ΄μ μ λ€μκ³Ό κ°μ λ€μν μ€μ μ ν리μΌμ΄μ μμ μ¬μ©λκ³ μμ΅λλ€:
- μ μμκ±°λ νλ«νΌ: μ ν μΆμ², κ²°μ κ²μ΄νΈμ¨μ΄ λ° λ°°μ‘ μ 곡μ 체λ₯Ό λμ μΌλ‘ λ‘λ©ν©λλ€. μλ₯Ό λ€μ΄, κΈλ‘λ² μ μμκ±°λ νλ«νΌμ κ³ κ°μ μμΉμ λ°λΌ λ€λ₯Έ κ²°μ μ 곡μ 체λ₯Ό ν΅ν©νκΈ° μν΄ λͺ¨λ νλλ μ΄μ μ μ¬μ©ν μ μμ΅λλ€. λΆλ―Έμμλ Stripeμ© νλ¬κ·ΈμΈμ, μ λ½μμλ PayPalμ΄λ Klarnaμ© νλ¬κ·ΈμΈμ λ‘λν μ μμ΅λλ€.
- μ½ν μΈ κ΄λ¦¬ μμ€ν (CMS): μ¬μ©μκ° CMSμ κΈ°λ₯μ νμ₯νκΈ° μν΄ νλ¬κ·ΈμΈμ μ€μΉνκ³ νμ±νν μ μλλ‘ ν©λλ€. CMSλ μ¬μ©μκ° SEO μ΅μ ν, μμ λ―Έλμ΄ ν΅ν© λλ μ½ν μΈ λΆμμ μν νλ¬κ·ΈμΈμ μ€μΉν μ μλλ‘ νμ©ν μ μμ΅λλ€.
- λμ보λ λ° λΆμ νλ«νΌ: λ€μν μμ ―κ³Ό μκ°νλ₯Ό λμ μΌλ‘ λ‘λ©ν©λλ€. κΈλ‘λ² λΆμ νλ«νΌμ Google Analytics, Adobe Analytics λλ Salesforceμ κ°μ λ€μν λ°μ΄ν° μμ€μ λν νλ¬κ·ΈμΈμ λ‘λν μ μμ΅λλ€.
- λ§μ΄ν¬λ‘νλ‘ νΈμλ μν€ν μ²: λκ·λͺ¨ μΉ μ ν리μΌμ΄μ μ λ 립μ μΌλ‘ λ°°ν¬ κ°λ₯ν λ§μ΄ν¬λ‘νλ‘ νΈμλμ μ§ν©μΌλ‘ ꡬμΆν©λλ€. λκΈ°μ μ λͺ¨λ νλλ μ΄μ μ μ¬μ©νμ¬ μΉ μ ν리μΌμ΄μ μ κ³μ κ΄λ¦¬, μ ν μΉ΄νλ‘κ·Έ λλ μ£Όλ¬Έ μ²λ¦¬μ κ°μ νΉμ λΉμ¦λμ€ κΈ°λ₯μ λ΄λΉνλ λ§μ΄ν¬λ‘νλ‘ νΈμλμ μ§ν©μΌλ‘ ꡬμΆν μ μμ΅λλ€.
- λμμΈ μμ€ν : μ¬λ¬ μ ν리μΌμ΄μ μμ UI μ»΄ν¬λνΈμ λμμΈ ν ν°μ 곡μ ν©λλ€. μ¬λ¬ λΈλλλ₯Ό κ°μ§ κΈλ‘λ² μ‘°μ§μ λͺ¨λ νλλ μ΄μ μ μ¬μ©νμ¬ λͺ¨λ μ ν리μΌμ΄μ μμ κ³΅ν΅ λμμΈ μμ€ν μ 곡μ νμ¬ μΌκ΄μ±μ 보μ₯νκ³ κ°λ° λ Έλ ₯μ μ€μΌ μ μμ΅λλ€.
λͺ¨λ νλλ μ΄μ μΌλ‘ λμ νλ¬κ·ΈμΈ μμ€ν ꡬμΆμ μν λͺ¨λ² μ¬λ‘
λͺ¨λ νλλ μ΄μ μΌλ‘ λμ νλ¬κ·ΈμΈ μμ€ν μ ꡬμΆν λ λͺ μ¬ν΄μΌ ν λͺ κ°μ§ λͺ¨λ² μ¬λ‘λ λ€μκ³Ό κ°μ΅λλ€:
- νλ¬κ·ΈμΈμ μκ³ μ§μ€μ μΌλ‘ μ μ§νκΈ°: κ° νλ¬κ·ΈμΈμ νΉμ κΈ°λ₯ μ‘°κ°μ λ΄λΉν΄μΌ ν©λλ€. μ΄λ κ² νλ©΄ νλ¬κ·ΈμΈμ μ μ§λ³΄μνκ³ μ λ°μ΄νΈνκΈ°κ° λ μ¬μμ§λλ€.
- λͺ νν νλ¬κ·ΈμΈ μΈν°νμ΄μ€ μ μνκΈ°: νλ¬κ·ΈμΈμ΄ νΈμ€νΈ μ ν리μΌμ΄μ κ³Ό μνΈ μμ©νλ λ°©μμ λν λͺ νν μΈν°νμ΄μ€λ₯Ό μ μν©λλ€. μ΄λ νλ¬κ·ΈμΈμ΄ νΈμ€νΈμ νΈνλλλ‘ λ³΄μ₯νκ³ νΈνμ±μ΄ κΉ¨μ§λ λ³κ²½μ λ°©μ§ν©λλ€.
- μλ§¨ν± λ²μ κ΄λ¦¬ μ¬μ©νκΈ°: νλ¬κ·ΈμΈμ λ²μ μ κ΄λ¦¬νκΈ° μν΄ μλ§¨ν± λ²μ κ΄λ¦¬λ₯Ό μ¬μ©ν©λλ€. μ΄λ κ² νλ©΄ λ³κ²½ μ¬νμ μΆμ νκ³ νΈνμ±μ 보μ₯νκΈ°κ° λ μ¬μμ§λλ€.
- λ¬Έμ μ 곡νκΈ°: νλ¬κ·ΈμΈμ λν λͺ ννκ³ κ°κ²°ν λ¬Έμλ₯Ό μ 곡ν©λλ€. μ΄λ μ¬μ©μκ° νλ¬κ·ΈμΈμ μ€μΉ, κ΅¬μ± λ° μ¬μ©νλ λ°©λ²μ μ΄ν΄νλ λ° λμμ΄ λ©λλ€.
- 보μ λͺ¨λ² μ¬λ‘ ꡬννκΈ°: μ ν리μΌμ΄μ κ³Ό νλ¬κ·ΈμΈμ μ·¨μ½μ μΌλ‘λΆν° 보νΈνκΈ° μν΄ λ³΄μ λͺ¨λ² μ¬λ‘λ₯Ό λ°λ¦ λλ€.
- νλ¬κ·ΈμΈ μ±λ₯ λͺ¨λν°λ§νκΈ°: νλ¬κ·ΈμΈμ μ±λ₯μ λͺ¨λν°λ§νμ¬ λ³λͺ© νμμ μλ³ν©λλ€. μ±λ₯μ κ°μ νκΈ° μν΄ μ½λλ₯Ό μ΅μ νν©λλ€.
- λ°°ν¬ μλννκΈ°: μ ν리μΌμ΄μ κ³Ό νλ¬κ·ΈμΈμ λ°°ν¬λ₯Ό μλνν©λλ€. μ΄λ μ€λ₯μ μνμ μ€μ΄κ³ μ λ°μ΄νΈκ° μ μνκ² λ°°ν¬λλλ‘ λ³΄μ₯ν©λλ€.
- μΌκ΄λ μ½λ© μ€νμΌ μ¬μ©νκΈ°: λͺ¨λ νλ¬κ·ΈμΈμμ μΌκ΄λ μ½λ© μ€νμΌμ μ μ©ν©λλ€. μ΄λ κ² νλ©΄ μ½λλ₯Ό μ½κ³ μ μ§λ³΄μνκΈ°κ° λ μ¬μμ§λλ€.
- λ¨μ ν μ€νΈ μμ±νκΈ°: νλ¬κ·ΈμΈμ΄ μ¬λ°λ₯΄κ² μλνλμ§ νμΈνκΈ° μν΄ λ¨μ ν μ€νΈλ₯Ό μμ±ν©λλ€.
- λ¦°ν° μ¬μ©νκΈ°: λ¦°ν°λ₯Ό μ¬μ©νμ¬ μ½λμμ μ€λ₯λ₯Ό μλμΌλ‘ νμΈν©λλ€.
κ²°λ‘
μλ°μ€ν¬λ¦½νΈ λͺ¨λ νλλ μ΄μ μ λμ νλ¬κ·ΈμΈ μμ€ν μ ꡬμΆνκΈ° μν κ°λ ₯νκ³ μ μ°ν λ©μ»€λμ¦μ μ 곡ν©λλ€. λͺ¨λ νλλ μ΄μ μ νμ©νμ¬ λ³ννλ μꡬμ¬νμ μ μν μ μλ λͺ¨λμμ΄κ³ νμ₯ κ°λ₯νλ©° μ μ§λ³΄μ μ©μ΄ν μ ν리μΌμ΄μ μ λ§λ€ μ μμ΅λλ€. μ΄ κΈμμ μ€λͺ ν λͺ¨λ² μ¬λ‘λ₯Ό λ°λ₯΄λ©΄ μ‘°μ§μ μꡬλ₯Ό μΆ©μ‘±νλ κ²¬κ³ νκ³ μμ ν νλ¬κ·ΈμΈ μμ€ν μ ꡬμΆν μ μμ΅λλ€.
μ΄ κΈ°μ μ κ΅μ μ μΈ λ§₯λ½μμ νΉν κ°μΉκ° μμΌλ©°, κΈ°μ μ΄ μμ ν λ³κ°μ μ ν리μΌμ΄μ μ λ°°ν¬νμ§ μκ³ λ νΉμ μ§μμ΄λ κ³ κ° λΆλ¬Έμ λ§κ² μννΈμ¨μ΄ μ 곡μ μ‘°μ ν μ μλλ‘ ν©λλ€. νμ§ κ²°μ κ²μ΄νΈμ¨μ΄ ν΅ν©λΆν° μ§μλ³ μ½ν μΈ μ 곡μ μ΄λ₯΄κΈ°κΉμ§, λͺ¨λ νλλ μ΄μ μ μ μΈκ³μ μΌλ‘ λ κ°μΈνλκ³ ν¨μ¨μ μΈ μ¬μ©μ κ²½νμ μ΄μ§ν©λλ€.